﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

using PAT.Entities;
using PAT.Services;
using PAT.Data.Bases;
using PAT.Util;

public partial class aspx_tal06_07_08_AdministrarOperacionesOT : System.Web.UI.Page
{
    #region Atributos

    /// <summary>
    /// Instancia de la clase Common
    /// </summary>
    private PAT.Util.Common instanciaCommon = new PAT.Util.Common();

    /// <summary>
    /// Objeto que contiene la información de la orden de trabajo
    /// </summary>
    private PatOrdenTrabajo ordenTrabajo;
    
    #endregion

    #region Eventos

    /// <summary>
    /// Evento de carga de la página
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        //Se valida si es la carga inicial de la página o si viene de un envio posterior
        if (!IsPostBack)
        {
            if (Request.QueryString["ok"] != null)
                ScriptManager.RegisterStartupScript(this, typeof(Page), "scrOK", "alert('Las operaciones de la orden de trabajo se han modificado satisfactoriamente');", true);
            Session.Remove("ordenTrabajo");
            UtilUI.BindListControl(ddlTipoOT, instanciaCommon.GetDocumentosPorEstadoYTipo(true, TiposDocumento.OrdenTrabajo), "IdDocumento", "DescripcionDocumento", true);
            ObtenerCargosOrden();
            ObtenerEmpleados();
            ObtenerEstadosOperacion();
            ObtenerTempario();
        }
        else
        {
            if (Session["ordenTrabajo"] != null)
                ordenTrabajo = (PatOrdenTrabajo)Session["ordenTrabajo"];
        }
    }

    /// <summary>
    /// Evento para salvar la información de las operaciones de la orden de trabajo
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void ibSave_Click(object sender, ImageClickEventArgs e)
    {
        //Se salva la información de la orden de trabajo y su colección de operaciones
        PatOrdenTrabajoService servicio = new PatOrdenTrabajoService();
        bool exito = servicio.DeepSave(ordenTrabajo, PAT.Data.DeepSaveType.IncludeChildren, new Type[] { typeof(TList<PatOrdenTrabajoOperacion>) });
        if (exito)
            ScriptManager.RegisterStartupScript(this, typeof(Page), "scrOKSav", "alert('La orden de trabajo fue modificada satisfactoriamente');", true);
        else
            ScriptManager.RegisterStartupScript(this, typeof(Page), "scrErrSav", "alert('" + servicio.ServiceProcessResult.Error + "');", true);
    }

    /// <summary>
    /// Evento para la salida del formulario sin guardar cambios
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void ibExit_Click(object sender, ImageClickEventArgs e)
    {
        Response.Redirect("../inicio/Home.aspx");
    }

    /// <summary>
    /// Evento para consultar la información de la orden de trabajo
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Consultar_Click(object sender, EventArgs e)
    {
        PatOrdenTrabajoService servicioOT = new PatOrdenTrabajoService();
        //Se intenta obtener la información de la orden de trabajo y su colección de operaciones
        Type[] typesToLoad = { typeof(PatListaPreciosTaller), typeof(TList<PatOrdenTrabajoOperacion>), typeof(PatTempario), typeof(PatEmpleado), typeof(PatCargoOrden), typeof(PatEstadoOperacion) };
        ordenTrabajo = servicioOT.DeepLoadByIdDocumentoNumeroOrden(int.Parse(ddlTipoOT.SelectedValue), int.Parse(txtNumeroOT.Text.Trim()), true, PAT.Data.DeepLoadType.IncludeChildren, typesToLoad);
        if (ordenTrabajo != null)
        {
            Session["ordenTrabajo"] = ordenTrabajo;

            ObtenerGrupoCatalogoVehiculo();
            lbGrupoCatalogo.Text = ((PatGrupoCatalogo)ViewState["grupoCatalogo"]).DescripcionGrupoCatalogo;

            dgTorreControl.DataSource = ordenTrabajo.PatOrdenTrabajoOperacionCollection;
            dgTorreControl.DataBind();
        }
        else
        {
            Session.Remove("ordenTrabajo");
            ViewState.Remove("grupoCatalogo");
            ordenTrabajo = new PatOrdenTrabajo();
            dgTorreControl.DataBind();
            ScriptManager.RegisterStartupScript(this, typeof(Page), "scrErrNoOT", "alert('No se encontró información de la orden de trabajo');", true);
            return;
        }
    }

    /// <summary>
    /// Evento para cancelar la edición de un item de la grilla de operaciones
    /// </summary>
    /// <param name="source"></param>
    /// <param name="e"></param>
    protected void dgTorreControl_CancelCommand(object source, DataGridCommandEventArgs e)
    {
        dgTorreControl.EditItemIndex = -1;
        dgTorreControl.DataSource = ordenTrabajo.PatOrdenTrabajoOperacionCollection;
        dgTorreControl.DataBind();
    }

    /// <summary>
    /// Evento para comenzar la edición de un item de la grilla de operaciones
    /// </summary>
    /// <param name="source"></param>
    /// <param name="e"></param>
    protected void dgTorreControl_EditCommand(object source, DataGridCommandEventArgs e)
    {
        dgTorreControl.EditItemIndex = e.Item.ItemIndex;
        dgTorreControl.DataSource = ordenTrabajo.PatOrdenTrabajoOperacionCollection;
        dgTorreControl.DataBind();
    }

    /// <summary>
    /// Evento para agregar y remover operaciones en la grilla
    /// </summary>
    /// <param name="source"></param>
    /// <param name="e"></param>
    protected void dgTorreControl_ItemCommand(object source, DataGridCommandEventArgs e)
    {
        if (e.CommandName == "Add")
        {
            DropDownList ddlCodigoOperacion = (DropDownList)e.Item.FindControl("ddlCodigoOperacion");
            DropDownList ddlCargoOperacion = (DropDownList)e.Item.FindControl("ddlCargoOperacion");
            if(!EsCargoValido(ordenTrabajo.IdCargoOrden, Convert.ToInt32(ddlCargoOperacion.SelectedValue)))
            {
                ScriptManager.RegisterStartupScript(this, typeof(Page), "scrErrCargo", "alert('El cargo seleccionado no es válido para la orden de trabajo');", true);
                return;
            }
            if(!ExisteOperacionEnOT(Convert.ToInt32(ddlCodigoOperacion.SelectedValue)))
            {
                PatTempario informacionOperacion = ObtenerOperacionTempario(Convert.ToInt32(ddlCodigoOperacion.SelectedValue));
                PatOrdenTrabajoOperacion operacion = new PatOrdenTrabajoOperacion();
                operacion.Activo = true;                
                operacion.IdCargoOperacion = byte.Parse(ddlCargoOperacion.SelectedValue);
                operacion.IdDocumento = ordenTrabajo.IdDocumento;
                operacion.IdOperacion = int.Parse(ddlCodigoOperacion.SelectedValue);
                operacion.IdOperacionSource = informacionOperacion;
                operacion.NumeroOrden = ordenTrabajo.NumeroOrden;

                double tiempo = ObtenerTiempoOperacion(((PatGrupoCatalogo)ViewState["grupoCatalogo"]).IdGrupoCatalogo, int.Parse(ddlCodigoOperacion.SelectedValue), byte.Parse(ddlCargoOperacion.SelectedValue));
                operacion.TiempoOriginalOperacion = Convert.ToDecimal(tiempo);
                operacion.TiempoLiquidado = Convert.ToDecimal(tiempo);

                operacion.ValorOperacion = Convert.ToDecimal(CalcularValorOperacion(informacionOperacion, byte.Parse(ddlCargoOperacion.SelectedValue), Convert.ToDouble(operacion.TiempoOriginalOperacion.Value)));

                //Se intenta asociar un empleado a la operación
                PatEmpleado empleado = instanciaCommon.GetEmpleadoMenorCargaTrabajo(informacionOperacion.IdTipoOperacion, ordenTrabajo.IdTaller);
                if (empleado != null)
                {
                    operacion.IdEmpleado = empleado.IdEmpleado;
                    operacion.IdEstadoOperacion = 1;
                }
                else
                    operacion.IdEstadoOperacion = 5;

                ordenTrabajo.PatOrdenTrabajoOperacionCollection.Add(operacion);

                //Se recalcula la fecha y hora estimada de entrega del vehículo
                DateTime fechaHoraEstimadaEntrega = instanciaCommon.GetEstimadoEntregaOT(ordenTrabajo.FechaEstimadaEntrega, ordenTrabajo.IdTaller, operacion.TiempoLiquidado.Value);
                ordenTrabajo.FechaEstimadaEntrega = fechaHoraEstimadaEntrega.Date;
                ordenTrabajo.HoraEstimadaEntrega = fechaHoraEstimadaEntrega;

                Session["ordenTrabajo"] = ordenTrabajo;
            }
            else
            {
                ScriptManager.RegisterStartupScript(this, typeof(Page), "scrErrOper", "alert('La operación seleccionada ya existe en la orden de trabajo');", true);
                return;
            }
        }
        else if (e.CommandName == "Delete")
        {
            //Se elimina la operación de la colección de operaciones de la orden de trabajo y se recalcula
            //la feha y hora de entrega
            DateTime fechaHoraEstimadaEntrega = instanciaCommon.GetEstimadoEntregaOT(ordenTrabajo.FechaEstimadaEntrega, ordenTrabajo.IdTaller, ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].TiempoLiquidado.Value * -1);
            ordenTrabajo.FechaEstimadaEntrega = fechaHoraEstimadaEntrega.Date;
            ordenTrabajo.HoraEstimadaEntrega = fechaHoraEstimadaEntrega;
            ordenTrabajo.PatOrdenTrabajoOperacionCollection.RemoveAt(e.Item.ItemIndex);
            Session["ordenTrabajo"] = ordenTrabajo;
        }

        dgTorreControl.DataSource = ordenTrabajo.PatOrdenTrabajoOperacionCollection;
        dgTorreControl.DataBind();
    }

    /// <summary>
    /// Evento para actualizar la información de una operación en la grilla
    /// </summary>
    /// <param name="source"></param>
    /// <param name="e"></param>
    protected void dgTorreControl_UpdateCommand(object source, DataGridCommandEventArgs e)
    {
        byte idCargoOperacion = byte.Parse(((DropDownList)e.Item.FindControl("ddlEditCargoOperacion")).SelectedValue);
        int idEmpleado = int.Parse(((DropDownList)e.Item.FindControl("ddlAsesor")).SelectedValue);
        decimal tiempo = decimal.Parse(((TextBox)e.Item.FindControl("txtTiempo")).Text);
        byte idEstadoOperacion = byte.Parse(((DropDownList)e.Item.FindControl("ddlEstado")).SelectedValue);

        PatOrdenTrabajoOperacion operacionSeleccionada = ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex];
        if (idCargoOperacion != operacionSeleccionada.IdCargoOperacion)
        {
            ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].IdCargoOperacion = idCargoOperacion;
            ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].IdCargoOperacionSource = null;
        }

        if (operacionSeleccionada.IdEmpleado.HasValue)
        {
            if (idEmpleado != operacionSeleccionada.IdEmpleado.Value)
            {
                ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].IdEmpleado = idEmpleado;
                ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].IdEmpleadoSource = null;
            }
        }
        else
        {
            ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].IdEmpleado = idEmpleado;
            ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].IdEmpleadoSource = null;
        }

        decimal tiempoOriginal = operacionSeleccionada.TiempoLiquidado.HasValue ? operacionSeleccionada.TiempoLiquidado.Value : operacionSeleccionada.TiempoOriginalOperacion.Value;
        if (tiempo != tiempoOriginal)
        {
            ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].TiempoLiquidado = tiempo;
            DateTime fechaHoraEstimadaEntrega = DateTime.MinValue;
            decimal diferenciaTiempo = 0;
            if (tiempo > tiempoOriginal)
            {
                diferenciaTiempo = tiempo - tiempoOriginal;
                fechaHoraEstimadaEntrega = instanciaCommon.GetEstimadoEntregaOT(ordenTrabajo.FechaEstimadaEntrega, ordenTrabajo.IdTaller, diferenciaTiempo);
            }
            else
            {
                diferenciaTiempo = tiempoOriginal - tiempo;
                fechaHoraEstimadaEntrega = instanciaCommon.GetEstimadoEntregaOT(ordenTrabajo.FechaEstimadaEntrega, ordenTrabajo.IdTaller, diferenciaTiempo * -1);
            }
            ordenTrabajo.FechaEstimadaEntrega = fechaHoraEstimadaEntrega.Date;
            ordenTrabajo.HoraEstimadaEntrega = fechaHoraEstimadaEntrega;
        }

        if (idEstadoOperacion != operacionSeleccionada.IdEstadoOperacion.Value)
        {
            ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].IdEstadoOperacion = idEstadoOperacion;
            ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].IdEstadoOperacionSource = null;
        }

        PatTempario informacionOperacion = ObtenerOperacionTempario(operacionSeleccionada.IdOperacion);
        ordenTrabajo.PatOrdenTrabajoOperacionCollection[e.Item.ItemIndex].ValorOperacion = Convert.ToDecimal(CalcularValorOperacion(informacionOperacion, idCargoOperacion, Convert.ToDouble(tiempo)));

        Session["ordenTrabajo"] = ordenTrabajo;
        dgTorreControl.EditItemIndex = -1;
        dgTorreControl.DataSource = ordenTrabajo.PatOrdenTrabajoOperacionCollection;
        dgTorreControl.DataBind();
    }

    /// <summary>
    /// Evento para realizar cambios de último momento antes de terminar el enlace de datos de la grilla
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void dgTorreControl_ItemDataBound(object sender, DataGridItemEventArgs e)
    {
        //Se enlazan a datos los distintos controles contenidos dentro de la grilla y se les asocia valor
        //por defecto
        PatOrdenTrabajoOperacion operacionSeleccionada = (PatOrdenTrabajoOperacion)e.Item.DataItem;
        if (e.Item.ItemType == ListItemType.Footer)
        {
            DropDownList ddlCodOper = (DropDownList)e.Item.FindControl("ddlCodigoOperacion");            
            ddlCodOper.DataTextField = "DescripcionOperacion";
            ddlCodOper.DataValueField = "IdOperacion";
            ddlCodOper.DataSource = (TList<PatTempario>)Session["tempario"];
            ddlCodOper.DataBind();
            ddlCodOper.Items.Insert(0, new ListItem(ConfigurationManager.AppSettings["EmptyListItemText"], String.Empty));

            DropDownList ddlCargo = (DropDownList)e.Item.FindControl("ddlCargoOperacion");
            ddlCargo.DataTextField = "DescripcionCargoOrden";
            ddlCargo.DataValueField = "IdCargoOrden";
            ddlCargo.DataSource = (TList<PatCargoOrden>)ViewState["cargosOrden"];
            ddlCargo.DataBind();
            ddlCargo.Items.Insert(0, new ListItem(ConfigurationManager.AppSettings["EmptyListItemText"], String.Empty));
        }
        if (e.Item.ItemType == ListItemType.EditItem)
        {
            DropDownList ddlCargo = (DropDownList)e.Item.FindControl("ddlEditCargoOperacion");
            ddlCargo.DataTextField = "DescripcionCargoOrden";
            ddlCargo.DataValueField = "IdCargoOrden";
            ddlCargo.DataSource = (TList<PatCargoOrden>)ViewState["cargosOrden"];
            ddlCargo.DataBind();
            ddlCargo.Items.Insert(0, new ListItem(ConfigurationManager.AppSettings["EmptyListItemText"], String.Empty));
            ddlCargo.SelectedValue = operacionSeleccionada.IdCargoOperacion.ToString();

            DropDownList ddlAsesor = (DropDownList)e.Item.FindControl("ddlAsesor");
            ddlAsesor.DataTextField = "NombreCompleto";
            ddlAsesor.DataValueField = "IdEmpleado";
            ddlAsesor.DataSource = (DataTable)Session["empleados"];
            ddlAsesor.DataBind();
            ddlAsesor.Items.Insert(0, new ListItem(ConfigurationManager.AppSettings["EmptyListItemText"], String.Empty));
            if (operacionSeleccionada.IdEmpleado.HasValue)
                ddlAsesor.SelectedValue = operacionSeleccionada.IdEmpleado.Value.ToString();

            DropDownList ddlEstado = (DropDownList)e.Item.FindControl("ddlEstado");
            ddlEstado.DataTextField = "DescripcionEstadoOperacion";
            ddlEstado.DataValueField = "IdEstadoOperacion";
            ddlEstado.DataSource = (TList<PatEstadoOperacion>)ViewState["estadosOperacion"];
            ddlEstado.DataBind();
            ddlEstado.Items.Insert(0, new ListItem(ConfigurationManager.AppSettings["EmptyListItemText"], String.Empty));
            ddlEstado.SelectedValue = operacionSeleccionada.IdEstadoOperacion.Value.ToString();
        }
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            Label lbCargo = (Label)e.Item.FindControl("lbCargo");
            lbCargo.Text = ObtenerDescripcionCargoOperacionXID(operacionSeleccionada.IdCargoOperacion);

            Label lbNombresEmpleado = (Label)e.Item.FindControl("lbAsesor");
            if (operacionSeleccionada.IdEmpleado.HasValue)
                lbNombresEmpleado.Text = ObtenerNombreCompletoEmpleadoXID(operacionSeleccionada.IdEmpleado.Value);

            Label lbEstadoOperacion = (Label)e.Item.FindControl("lbEstado");
            lbEstadoOperacion.Text = ObtenerDescripcionEstadoOperacionXID(operacionSeleccionada.IdEstadoOperacion.Value);
        }
    }

    /// <summary>
    /// Evento que se dispara al cambiar el elemento seleccionado en el combo de operaciones en la grilla
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void ddlCodigoOperacion_SelectedIndexChanged(object sender, EventArgs e)
    {
        DropDownList ddlCodigoOperacion = (DropDownList)sender;
        if (ddlCodigoOperacion.SelectedValue != string.Empty)
        {
            DataGridItem rowParent = ddlCodigoOperacion.Parent.Parent as DataGridItem;
            ((Label)rowParent.FindControl("lbDescripcionOperacion")).Text = ddlCodigoOperacion.SelectedItem.Text;
        }
    }

    #endregion

    #region Métodos

    /// <summary>
    /// Obtiene el grupo de catálogo para el vehículo asociado a la orden de trabajo y almacena dicha
    /// información en el ViewState de la página
    /// </summary>
    private void ObtenerGrupoCatalogoVehiculo()
    {
        PatGrupoCatalogo output = new PatGrupoCatalogo();
        output = new PatGrupoCatalogoService().GetByIdGrupoCatalogo(
                    new PatCatalogoVehiculoService().GetByIdCatalogo(
                        new PatVehiculoService().GetByIdVehiculo(ordenTrabajo.IdVehiculo).IdCatalogo).IdGrupoCatalogo);
        ViewState["grupoCatalogo"] = output;
    }

    /// <summary>
    /// Obtiene el tiempo que se demora un asesor llevando a cabo una operación mecanica, el tiempo varia
    /// dependiendo del cargo y el grupo de catálogo del vehículo
    /// </summary>
    /// <param name="idGrupoCatalogo">Identificador del grupo de catálogo</param>
    /// <param name="idOperacion">Identificador de la operación</param>
    /// <param name="idCargo">Identificador del cargo de la orden</param>
    /// <returns>Tiempo estimado para la operación</returns>
    private double ObtenerTiempoOperacion(short idGrupoCatalogo, int idOperacion, byte idCargo)
    {
        double output = 0;
        PatTiempoTallerService servicio = new PatTiempoTallerService();
        PatTiempoTaller tiempoGrupo = servicio.GetByIdGrupoCatalogoIdOperacion(idGrupoCatalogo, idOperacion);
        if (tiempoGrupo != null && tiempoGrupo.Activo)
        {
            if (idCargo == Convert.ToByte(CargosOrden.Garantia))
                output = Convert.ToDouble(tiempoGrupo.TiempoGarantia);
            else if (idCargo == Convert.ToByte(CargosOrden.Cliente) || idCargo == Convert.ToByte(CargosOrden.Seguros))
                output = Convert.ToDouble(tiempoGrupo.TiempoCliente);
            else if (idCargo == Convert.ToByte(CargosOrden.Interno))
                output = Convert.ToDouble(tiempoGrupo.TiempoMecanico);
        }
        else
            output = Convert.ToDouble((((TList<PatTempario>)Session["tempario"]).Find(delegate(PatTempario p) { return p.IdOperacion == idOperacion; })).TiempoEstandar);
        return output;
    }

    /// <summary>
    /// Obtiene el tempario de operaciones del taller y lo almacena en la Session
    /// </summary>
    private void ObtenerTempario()
    {
        TList<PatTempario> output = new TList<PatTempario>();
        output = new PatTemparioService().GetAll();
        output = output.FindAll(delegate(PatTempario p) { return p.Activo == true; });
        Session["tempario"] = output;
    }

    /// <summary>
    /// Obtiene el listado de empleados del taller, concatena nombres con apellidos y almacena la informacióm
    /// en la Session
    /// </summary>
    private void ObtenerEmpleados()
    {
        TList<PatEmpleado> output = new TList<PatEmpleado>();
        output = new PatEmpleadoService().GetAll();
        output = output.FindAll(delegate(PatEmpleado p) { return p.Activo && (p.IdTipoEmpleado == Convert.ToInt16(PAT.Util.TipoEmpleado.RecepcionistaTaller) || p.IdTipoEmpleado == Convert.ToInt16(PAT.Util.TipoEmpleado.TecnicoTaller)); });
        DataSet dsEmpleados = output.ToDataSet(false);
        DataTable dtEmpleados = dsEmpleados.Tables[0];
        dtEmpleados.Columns.Add("NombreCompleto", typeof(String), "Nombres +' '+ Apellidos");
        Session["empleados"] = dtEmpleados;
    }

    /// <summary>
    /// Obtiene el nombre completo de un empleado dado su ID
    /// </summary>
    /// <param name="idEmpleado">Identificador del empleado</param>
    /// <returns>Nombre Completo del empleado</returns>
    private string ObtenerNombreCompletoEmpleadoXID(int idEmpleado)
    {
        string output = string.Empty;
        DataRow[] empleado = ((DataTable)Session["empleados"]).Select("IdEmpleado = " + idEmpleado.ToString());
        if (empleado != null && empleado.Length != 0)
            output = empleado[0]["NombreCompleto"].ToString();
        return output;
    }

    /// <summary>
    /// Obtiene los posibles cargos de una orden de trabajo y los almacena en el ViewState
    /// </summary>
    private void ObtenerCargosOrden()
    {
        TList<PatCargoOrden> output = new TList<PatCargoOrden>();
        output = new PatCargoOrdenService().GetAll();
        output = output.FindAll(delegate(PatCargoOrden p) { return p.Activo; });
        ViewState["cargosOrden"] = output;
    }

    /// <summary>
    /// Obtiene la descripción de un cargo de una orden de trabajo dado su ID
    /// </summary>
    /// <param name="idCargo">Identificador del cargo de la orden</param>
    /// <returns>Descripción del cargo</returns>
    private string ObtenerDescripcionCargoOperacionXID(byte idCargo)
    {
        string output = string.Empty;
        PatCargoOrden cargo = ((TList<PatCargoOrden>)ViewState["cargosOrden"]).Find(delegate(PatCargoOrden p) { return p.IdCargoOrden == idCargo; });
        if (cargo != null)
            output = cargo.DescripcionCargoOrden;
        return output;
    }

    /// <summary>
    /// Obtiene los posibles estados en los que se puede encontrar una operación y los almacena en el
    /// ViewState del formulario
    /// </summary>
    private void ObtenerEstadosOperacion()
    {
        TList<PatEstadoOperacion> output = new TList<PatEstadoOperacion>();
        output = new PatEstadoOperacionService().GetAll();
        output = output.FindAll(delegate(PatEstadoOperacion p) { return p.Activo; });
        ViewState["estadosOperacion"] = output;
    }

    /// <summary>
    /// Obtiene la descripción de un estado de una operación dado su ID
    /// </summary>
    /// <param name="idEstadoOperacion">Identificador del estado de la operación</param>
    /// <returns>Descripción del estado de la operación</returns>
    private string ObtenerDescripcionEstadoOperacionXID(byte idEstadoOperacion)
    {
        string output = string.Empty;
        PatEstadoOperacion estadoOperacion = ((TList<PatEstadoOperacion>)ViewState["estadosOperacion"]).Find(delegate(PatEstadoOperacion p) { return p.IdEstadoOperacion == idEstadoOperacion; });
        if (estadoOperacion != null)
            output = estadoOperacion.DescripcionEstadoOperacion;
        return output;
    }

    /// <summary>
    /// Verifica si un cargo seleccionado en la grilla de operaciones es válido para la orden de trabajo
    /// seleccionada
    /// </summary>
    /// <param name="cargoPrincipalOT">Id del Cargo de la orden de trabajo</param>
    /// <param name="cargoEscogido">Id del Cargo de la operación seleccionada</param>
    /// <returns>True en caso de ser un cargo valido; False en caso contrario</returns>
    private bool EsCargoValido(int cargoPrincipalOT, int cargoEscogido)
    {
        bool cargoValido = true;
        if (cargoPrincipalOT == Convert.ToInt32(CargosOrden.Seguros))
            cargoValido = true;
        else if (cargoPrincipalOT == Convert.ToInt32(CargosOrden.Cliente))
        {
            if (cargoEscogido == Convert.ToInt32(CargosOrden.Seguros))
                cargoValido = false;
        }
        else if (cargoPrincipalOT == Convert.ToInt32(CargosOrden.Garantia))
        {
            if (cargoEscogido == Convert.ToInt32(CargosOrden.Seguros) || cargoEscogido == Convert.ToInt32(CargosOrden.Cliente))
                cargoValido = false;
        }
        else
        {
            if (cargoEscogido == Convert.ToInt32(CargosOrden.Seguros) || cargoEscogido == Convert.ToInt32(CargosOrden.Cliente) || cargoEscogido == Convert.ToInt32(CargosOrden.Garantia))
                cargoValido = false;
        }
        return cargoValido;
    }

    /// <summary>
    /// Verifica si la operación ya se encuentra agregada a la orden de trabajo
    /// </summary>
    /// <param name="idOperacion">Identificador de la operación</param>
    /// <returns>True en caso de existencia de la operación; False en caso contrario</returns>
    private bool ExisteOperacionEnOT(int idOperacion)
    {
        bool existeOperacion = false;
        PatOrdenTrabajoOperacion operacion = ordenTrabajo.PatOrdenTrabajoOperacionCollection.Find(delegate(PatOrdenTrabajoOperacion p) { return p.IdOperacion == idOperacion; });
        if (operacion != null)
            existeOperacion = true;
        return existeOperacion;
    }

    /// <summary>
    /// Realiza el cálculo del valor final de una operación dependiendo del tipo de liquidación de
    /// la misma
    /// </summary>
    /// <param name="operacion">Operación del tempario sobre la que se quiere realizar el calculo</param>
    /// <param name="idCargo">Identificador del cargo seleccionado para la operación</param>
    /// <param name="tiempo">Tiempo especificado en la grilla de operaciones</param>
    /// <returns>Valor calculado para la operación</returns>
    private double CalcularValorOperacion(PatTempario operacion, byte idCargo, double tiempo)
    {
        double valorOperacion = 0;
        if (operacion.IdTipoLiquidacion == 1)
        {
            if (idCargo == Convert.ToByte(CargosOrden.Garantia))
                valorOperacion = Convert.ToDouble(ordenTrabajo.IdListaPreciosSource.ValorHoraGarantia) * tiempo;
            else if (idCargo == Convert.ToByte(CargosOrden.Cliente) || idCargo == Convert.ToByte(CargosOrden.Seguros))
                valorOperacion = Convert.ToDouble(ordenTrabajo.IdListaPreciosSource.ValorHoraCliente) * tiempo;
            else if (idCargo == Convert.ToByte(CargosOrden.Interno))
                valorOperacion = Convert.ToDouble(ordenTrabajo.IdListaPreciosSource.ValorHoraInterno) * tiempo;
        }
        else if (operacion.IdTipoLiquidacion == 2)
        {
            if (idCargo == Convert.ToByte(CargosOrden.Interno))
                valorOperacion = Convert.ToDouble(operacion.ValorInternoTaller);
            else
                valorOperacion = Convert.ToDouble(operacion.ValorOperacion);
        }
        return valorOperacion;
    }
    
    /// <summary>
    /// Obtiene una operación del tempario
    /// </summary>
    /// <param name="idOperacion">Identificador de la operación</param>
    /// <returns>Objeto con la información de la operación</returns>
    private PatTempario ObtenerOperacionTempario(int idOperacion)
    {
        PatTempario output = null;
        TList<PatTempario> tempario = (TList<PatTempario>)Session["tempario"];
        output = tempario.Find(delegate(PatTempario p) { return p.IdOperacion == idOperacion; });
        return output;
    }

    #endregion
}